package com.lzy.business.facade;

import com.github.pagehelper.PageInfo;
import com.lzy.base.apis.SysUserRoleServiceApi;
import com.lzy.base.dtos.SysUserRoleDto;
import com.lzy.base.service.SysUserRoleService;
import com.lzy.business.request.AgencyManagementRequest;
import com.lzy.business.response.AgencyManagementReponse;
import com.lzy.business.response.AgentProtocolDtoReponse;
import com.lzy.common.apis.AreaServiceApi;
import com.lzy.common.dtos.AreaDto;
import com.lzy.framework.core.datasource.multiple.DataSource;
import com.lzy.framework.core.datasource.multiple.DataSourceHolder;
import com.lzy.framework.core.ensure.Ensure;
import com.lzy.framework.core.exceptions.XBusinessException;
import com.lzy.framework.core.orm.db.Pager;
import com.lzy.framework.core.utils.StringUtil;
import com.lzy.framework.tools.date.DateStyle;
import com.lzy.framework.tools.date.DateUtils;
import com.lzy.framework.tools.kv.KvClient;
import com.lzy.framework.tools.kv.detail.DistributeLockProcessor;
import com.lzy.member.apis.MemberUserServiceApi;
import com.lzy.member.dtos.MemberUserDto;
import com.lzy.product.apis.*;
import com.lzy.product.constants.AgentOrderEnum;
import com.lzy.product.dtos.ProductUserDto;
import com.lzy.product.dtos.agent.AgentMemberProtocolDto;
import com.lzy.product.dtos.agent.AgentProtocolCommissionDto;
import com.lzy.product.dtos.agent.AgentProtocolDto;
import com.lzy.product.dtos.agent.AgentProtocolSystemDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class AgencyManagementFacade {
    @Autowired
    private MemberUserServiceApi memberUserServiceApi;

    @Autowired
    private SysUserRoleServiceApi sysUserRoleServiceApi;

    @Autowired
    private ProductUserServiceApi productUserServiceApi;

    @Autowired
    private AreaServiceApi areaServiceApi;

    @Autowired
    private AgentMemberProtocolServiceApi agentMemberProtocolServiceApi;

    @Autowired
    private AgentProtocolSystemServiceApi agentProtocolSystemServiceApi;

    @Autowired
    private AgentSystemServiceApi agentSystemServiceApi;

    @Autowired
    private AgentProtocolServiceApi agentProtocolServiceApi;

    @Autowired
    private AgentProtocolCommissionServiceApi agentProtocolCommissionServiceApi;

    @Autowired
    private KvClient kvClient;


    private static final Logger LOGGER = LoggerFactory.getLogger(AgencyManagementFacade.class);

    /**
     * 新增代理商
     *
     * @param userDto
     * @param loginUserId 登陆用户id
     * @return
     */
    public ProductUserDto addAgent(ProductUserDto userDto, Long loginUserId) {
        Ensure.that(userDto).isNotNull("07000001");
        ProductUserDto productUserDto = productUserServiceApi.queryByPhone(userDto.getPhone());
        Ensure.that(productUserDto).isNull("01001623");
        MemberUserDto memberUserDto = toMemberUserDto(userDto, loginUserId);
        userDto.setAgentNumber(generateNumber(userDto));
        //取得体系id
        AgentProtocolSystemDto agentProtocolSystemDto = new AgentProtocolSystemDto();
        agentProtocolSystemDto.setProtocolId(userDto.getAgentProtocol());
        userDto.setSystemId(agentProtocolServiceApi.findById(userDto.getAgentProtocol()).getSystemId());
        userDto.setState(0);
        userDto.setLoginName(userDto.getPhone());
        userDto.setAgentTime(DateUtils.getNow(DateStyle.YYYY_MM_DD_HH_MM_SS));
        //保存sys_user_admin
        Long productUserId = productUserServiceApi.insert(userDto);
        Ensure.that(productUserId.intValue() > 0).isTrue("01001501");
        //保存agent_member_protocol
        AgentMemberProtocolDto agentMemberProtocolDto = new AgentMemberProtocolDto();
        agentMemberProtocolDto.setCreateUser(loginUserId);
        agentMemberProtocolDto.setProtocolId(userDto.getAgentProtocol());
        agentMemberProtocolDto.setMemberId(productUserId);
        //保存agent_member_protocol
        agentMemberProtocolServiceApi.insert(agentMemberProtocolDto);
        SysUserRoleDto sysUserRoleDto = new SysUserRoleDto();
        sysUserRoleDto.setUserId(productUserId);
        sysUserRoleDto.setRoleId(Long.valueOf(5));
        Ensure.that(sysUserRoleServiceApi.addUserRole(sysUserRoleDto)).isTrue("06000024");
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
        //保存member_user
        try {
            //查找数据库中是否已存在该用户
            MemberUserDto dbMemberUserDto = memberUserServiceApi.findMemberByMobile(userDto.getPhone());
            if (dbMemberUserDto != null) {
                dbMemberUserDto.setIDNumber(userDto.getIdNumber());
                dbMemberUserDto.setName(userDto.getName());
                dbMemberUserDto.setCityCode(userDto.getCityCode());
                dbMemberUserDto.setAddress(memberUserDto.getCityName());
                memberUserServiceApi.updateMemberInfo(dbMemberUserDto);
            } else {
                memberUserServiceApi.addMember(memberUserDto);
            }
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("代理商管理新增memberUser失败");
            throw e;
        } finally {
            DataSourceHolder.clearDataSource();
        }
        return userDto;
    }

    /**
     * toMemberUserDto
     *
     * @param productUserDto
     * @return
     */
    private MemberUserDto toMemberUserDto(ProductUserDto productUserDto, Long loginUserId) {
        MemberUserDto memberUserDto = new MemberUserDto();
        memberUserDto.setName(productUserDto.getName());
        memberUserDto.setAccount(productUserDto.getPhone());
        memberUserDto.setIDNumber(productUserDto.getIdNumber());
        memberUserDto.setCreateUser(loginUserId);
        memberUserDto.setCityCode(productUserDto.getCityCode());
        AreaDto areaDto = areaServiceApi.findAreaByCityCode(productUserDto.getCityCode());
        memberUserDto.setAddress(areaDto.getName());
        return memberUserDto;
    }

    /**
     * 生成代理商编号 地区编码+年月+4位流水号
     *
     * @param userDto
     * @return
     */
    private String generateNumber(ProductUserDto userDto) {
        return kvClient.lockForProcess(AgentOrderEnum.AGENT_NUMBER + userDto.getCityCode(), 3000, new DistributeLockProcessor<String>() {
            @Override
            public String process() throws XBusinessException {
                SimpleDateFormat format = new SimpleDateFormat("yyyyMM");
                String agentNumber = productUserServiceApi.maxiNumber(getExpression());
                if (StringUtil.isBlank(agentNumber)) {
                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append(userDto.getCityCode());
                    stringBuilder.append(format.format(new Date()));
                    stringBuilder.append("0001");
                    return stringBuilder.toString();
                } else {
                    //取得最大编号+1
                    Integer serialNumber = Integer.valueOf(agentNumber.substring(agentNumber.length() - 4, agentNumber.length())) + 1;
                    return agentNumber.substring(0, agentNumber.length() - 4) + serialNumber.toString();
                }
            }
        });
    }

    /**
     * 正则表达式 用于匹配数据库生成代理商编号
     *
     * @return
     */
    private String getExpression() {
        return "^[0-9][0-9][0-9][0-9][0-9][0-9]" + new SimpleDateFormat("yyyyMM").format(new Date()) + "[0-9][0-9][0-9][0-9]$";
    }

    /**
     * 代理商查询
     *
     * @param request
     * @return
     */
    public PageInfo searchAgents(AgencyManagementRequest request) {
        DataSourceHolder.clearDataSource();
        //拼接子级id
        StringBuilder areaDtostr = new StringBuilder();
        if (request.getCityCode() != null) {
            AreaDto areaDto = areaServiceApi.findAreaByCityCode(request.getCityCode());
            List<AreaDto> cityCollection = new ArrayList<>();
            List<AreaDto> countryCollection = new ArrayList<>();
            areaDtostr.append(areaDto.getCityCode() + ",");
            /**
             * 1省 2市 3县
             */
            if (areaDto.getLevel().equals(1)) {
                cityCollection = queryCity(2, areaDto.getCityCode(), 1);
                for (AreaDto cityArea : cityCollection) {
                    areaDtostr.append(cityArea.getCityCode() + ",");
                    countryCollection = queryCity(3, cityArea.getCityCode(), 1);
                    for (AreaDto countryArea : countryCollection) {
                        areaDtostr.append(countryArea.getCityCode() + ",");
                    }
                }
            } else if (areaDto.getLevel().equals(2)) {
                countryCollection = queryCity(3, areaDto.getCityCode(), 1);
                for (AreaDto countryArea : countryCollection) {
                    areaDtostr.append(countryArea.getCityCode() + ",");
                }
            }
        }
        Pager pager = new Pager();
        pager.setPageSize(request.getPageSize());
        pager.setPageNum(request.getPageNum());
        ProductUserDto productUserDto = new ProductUserDto();
        productUserDto.setCityCodeStr(areaDtostr.toString());
        productUserDto.setPhone(request.getPhoneOrName());
        PageInfo pageInfo = productUserServiceApi.queryAgents(pager, productUserDto);
        List<ProductUserDto> productUserDtoList = pageInfo.getList();
        List<AgencyManagementReponse> result = new ArrayList<>();
        for (ProductUserDto productUserDto1 : productUserDtoList) {
            AgencyManagementReponse reponse = new AgencyManagementReponse();
            reponse.setId(productUserDto1.getId());
            reponse.setCreateDate(productUserDto1.getCreateTime());
            reponse.setPhone(productUserDto1.getPhone());
            reponse.setName(productUserDto1.getName());
            reponse.setSystem(agentSystemServiceApi.findById(productUserDto1.getSystemId()).getName());
            reponse.setAgentNumber(productUserDto1.getAgentNumber());
            reponse.setAgentTime(StringUtil.isBlank(productUserDto1.getAgentTime()) ? "" : productUserDto1.getAgentTime().substring(0, productUserDto1.getAgentTime().lastIndexOf(".")));
            if (productUserDto1.getUserId() != null) {
                ProductUserDto superProductUserDto = productUserServiceApi.findById(productUserDto1.getUserId());
                if (superProductUserDto != null) {
                    reponse.setSuperior(superProductUserDto.getName());
                }
            }
            reponse.setState(productUserDto1.getState());
            DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
            MemberUserDto memberUserDto = memberUserServiceApi.findMemberByMobile(productUserDto1.getPhone());
            if (memberUserDto != null) {
                reponse.setNickName(memberUserDto.getNickName());
                reponse.setSaleMan(memberUserDto.getId());
            }
            if (productUserDto1.getCityCode() != null) {
                AreaDto areaDto = areaServiceApi.findAreaByCityCode(productUserDto1.getCityCode());
                String address = "";
                if (areaDto != null && areaDto.getLevel() != null) {
                    if (areaDto.getLevel() == 3) {
                        AreaDto areaDto1 = areaServiceApi.findAreaByCityCode(areaDto.getParentId());
                        AreaDto areaDto2 = areaServiceApi.findAreaByCityCode(areaDto1.getParentId());
                        address = areaDto2.getName() + " " + areaDto1.getName() + " " + areaDto.getName();
                    }
                    if (areaDto.getLevel() == 2) {
                        AreaDto areaDto3 = areaServiceApi.findAreaByCityCode(areaDto.getParentId());
                        address = areaDto3.getName() + " " + areaDto.getName();
                    }
                    if (areaDto.getLevel() == 1) {
                        address = areaDto.getName();
                    }
                    reponse.setLocation(address);
                }
            }

            DataSourceHolder.clearDataSource();
            result.add(reponse);
        }
        pageInfo.setList(result);
        return pageInfo;
    }

    /**
     * 查找代理商下级
     *
     * @param id
     * @return
     */
    public List<AgencyManagementReponse> searchChilds(Long id) {
        Ensure.that(id).isNotNull("07000001");
        List<AgencyManagementReponse> result = new ArrayList<>();
        ProductUserDto productUserDto = productUserServiceApi.findById(id);
        ProductUserDto param = new ProductUserDto();
        param.setUserId(productUserDto.getId());
        List<ProductUserDto> productUserDtoList = productUserServiceApi.query(param);
        for (ProductUserDto productUserDto1 : productUserDtoList) {
            AgencyManagementReponse reponse = new AgencyManagementReponse();
            reponse.setPhone(productUserDto1.getPhone());
            reponse.setCreateDate(productUserDto1.getCreateTime());
            reponse.setAgentNumber(productUserDto1.getAgentNumber());
            reponse.setSystem(agentSystemServiceApi.findById(productUserDto1.getSystemId()).getName());
            reponse.setState(productUserDto1.getState());
            reponse.setId(productUserDto1.getId());
            DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
            MemberUserDto memberUserDto = memberUserServiceApi.findMemberByMobile(productUserDto1.getPhone());
            reponse.setName(memberUserDto.getName());
            reponse.setNickName(memberUserDto.getNickName());
            reponse.setLocation(memberUserDto.getAddress());
            DataSourceHolder.clearDataSource();
            result.add(reponse);
        }
        return result;
    }


    /**
     * 查看代理商信息
     */
    public AgencyManagementReponse queryAgency(Long userId) {
        DataSourceHolder.clearDataSource();
        Ensure.that(userId).isNotNull("07000001");
        AgencyManagementReponse agencyManagementReponse = new AgencyManagementReponse();
        ProductUserDto productUserDto = productUserServiceApi.findById(userId);
        Ensure.that(productUserDto).isNotNull("01001505");
        agencyManagementReponse.setPhone(productUserDto.getPhone());
        agencyManagementReponse.setState(productUserDto.getState());
        agencyManagementReponse.setSystem(agentSystemServiceApi.findById(productUserDto.getSystemId()).getName());
        agencyManagementReponse.setCreateDate(productUserDto.getCreateTime());
        agencyManagementReponse.setAgentNumber(productUserDto.getAgentNumber());
        agencyManagementReponse.setId(productUserDto.getId());
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
        MemberUserDto memberUserDto = memberUserServiceApi.findMemberByMobile(productUserDto.getPhone());
        DataSourceHolder.clearDataSource();
        agencyManagementReponse.setNickName(memberUserDto.getNickName());
        agencyManagementReponse.setName(memberUserDto.getName());
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
        AreaDto areaDto = areaServiceApi.findAreaByCityCode(productUserDto.getCityCode());
        String location = "";
        if (areaDto != null) {
            location = areaDto.getName();
        } else {
            location = memberUserDto.getAddress();
        }
        if (areaDto != null && !areaDto.getLevel().equals(1)) {
            AreaDto parent = areaServiceApi.findAreaByCityCode(areaDto.getParentId());
            if (parent != null) {
                location = parent.getName() + " " + location;
            }
            parent = areaServiceApi.findAreaByCityCode(parent.getParentId());
            if (parent != null) {
                location = parent.getName() + " " + location;
            }
        }
        DataSourceHolder.clearDataSource();
        agencyManagementReponse.setLocation(location);
        AgentMemberProtocolDto agentMemberProtocolDto = new AgentMemberProtocolDto();
        agentMemberProtocolDto.setMemberId(productUserDto.getId());
        agentMemberProtocolDto.setDeleted(Boolean.FALSE);
        List<AgentMemberProtocolDto> agentMemberProtocolDtoList = agentMemberProtocolServiceApi.query(agentMemberProtocolDto);
        List<AgentProtocolDtoReponse> agentProtocolDtoReponseList = new ArrayList<>();
        for (AgentMemberProtocolDto agentMemberProtocolDto1 : agentMemberProtocolDtoList) {
            AgentProtocolDtoReponse agentProtocolDtoReponse = new AgentProtocolDtoReponse();
            agentProtocolDtoReponse.setAgentProtocolDto(agentProtocolServiceApi.findById(agentMemberProtocolDto1.getProtocolId()));
            AgentProtocolCommissionDto agentProtocolCommissionDto = new AgentProtocolCommissionDto();
            agentProtocolCommissionDto.setSystemId(productUserDto.getSystemId());
            agentProtocolCommissionDto.setProtocolId(agentMemberProtocolDto1.getProtocolId());
            agentProtocolCommissionDto.setType(1);
            List<AgentProtocolCommissionDto> agentProtocolCommissionDtoList = agentProtocolCommissionServiceApi.query(agentProtocolCommissionDto);
            if (null != agentProtocolCommissionDtoList && agentProtocolCommissionDtoList.size() == 1) {
                switch (agentProtocolCommissionDtoList.get(0).getMode().intValue()) {
                    case 1:
                        agentProtocolDtoReponse.setPartialCommission(agentProtocolCommissionDtoList.get(0).getValue() == null ? "" : agentProtocolCommissionDtoList.get(0).getValue() + "%");
                        break;
                    case 2:
                        agentProtocolDtoReponse.setPartialCommission(agentProtocolCommissionDtoList.get(0).getValue() == null ? "" : agentProtocolCommissionDtoList.get(0).getValue() + "元");
                        break;
                }
            }
            agentProtocolDtoReponseList.add(agentProtocolDtoReponse);
        }
        agencyManagementReponse.setAgentProtocols(agentProtocolDtoReponseList);
        AgentProtocolDto agentProtocol = agentProtocolServiceApi.selectDetailById(agentMemberProtocolDtoList.get(0).getProtocolId());
        List<AgentProtocolCommissionDto> agentProtocolCommissionDtoList = agentProtocolCommissionServiceApi.selectByProtocolIdAndSystemId(agentProtocol.getId(), agentProtocol.getSystemId(), null);
        if (!agentProtocolCommissionDtoList.isEmpty() && agentProtocolCommissionDtoList.size() > 0) {
            String suffix = agentProtocolCommissionDtoList.get(0).getMode().equals(1) ? "%" : "元";
            for (int i = 0; i < agentProtocolCommissionDtoList.size(); i++) {
                if (agentProtocolCommissionDtoList.get(i).getType().equals(2)) {
                    String agentCommission = agencyManagementReponse.getAgentCommission() == null ? "" : agencyManagementReponse.getAgentCommission();
                    agencyManagementReponse.setAgentCommission(agentCommission + agentProtocolCommissionDtoList.get(i).getValue() + suffix);
                    if (i != agentProtocolCommissionDtoList.size() - 1) {
                        agencyManagementReponse.setAgentCommission(agencyManagementReponse.getAgentCommission() + "、");
                    }
                }
            }
        }
        agencyManagementReponse.setAgentCommission(StringUtil.isBlank(agencyManagementReponse.getAgentCommission()) ? "无" : agencyManagementReponse.getAgentCommission());
        return agencyManagementReponse;
    }


    /**
     * 查询省市县地址下拉框内容
     *
     * @param type     1、省 2、市 3、县
     * @param cityCode 城市编码
     * @param isAgent  1只查询有代理商的区域
     * @return
     */
    public List<AreaDto> queryCity(Integer type, Integer cityCode, Integer isAgent) {
        DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
        Ensure.that(type).isNotNull("07000001");
        Ensure.that(isAgent).isNotNull("07000001");
        List<AreaDto> areaDtoList = areaServiceApi.queryAllProvince();
        List<AreaDto> allCityCode = new ArrayList<>();
        List<AreaDto> result = new ArrayList<>();
        if (isAgent.equals(1)) {
            DataSourceHolder.clearDataSource();
            List<Integer> citycodeList = productUserServiceApi.queryAllCitycode();
            DataSourceHolder.setDataSource(DataSource.DATASOURCE_COMMON);
            for (Integer c : citycodeList) {
                AreaDto areaDto = areaServiceApi.findAreaByCityCode(c);
                if (areaDto == null) {
                    continue;
                }
                allCityCode.add(areaDto);
                if (areaDto.getLevel().equals(3)) {
                    AreaDto parent = areaServiceApi.findAreaByCityCode(areaDto.getParentId());
                    if (parent != null && !allCityCode.contains(parent)) {
                        allCityCode.add(parent);
                        parent = areaServiceApi.findAreaByCityCode(parent.getParentId());
                        if (parent != null && !allCityCode.contains(parent)) {
                            allCityCode.add(parent);
                        }
                    }
                }
                if (areaDto.getLevel().equals(2)) {
                    AreaDto parent = areaServiceApi.findAreaByCityCode(areaDto.getParentId());
                    if (parent != null && !allCityCode.contains(parent)) {
                        allCityCode.add(parent);
                    }
                }
            }
        }
        switch (type.intValue()) {
            case 1:
                if (isAgent.equals(1)) {
                    for (AreaDto areaDto : areaDtoList) {
                        if (allCityCode.contains(areaDto)) {
                            result.add(areaDto);
                        }
                    }
                } else {
                    result.addAll(areaDtoList);
                }
                break;
            case 2:
                List<AreaDto> cityList = areaServiceApi.queryAllCity(cityCode);
                if (isAgent.equals(1)) {
                    for (AreaDto areaDto : cityList) {
                        if (allCityCode.contains(areaDto)) {
                            result.add(areaDto);
                        }
                    }
                } else {
                    result.addAll(cityList);
                }
                break;
            case 3:
                List<AreaDto> countyList = areaServiceApi.queryAllArea(cityCode);
                if (isAgent.equals(1)) {
                    for (AreaDto areaDto : countyList) {
                        if (allCityCode.contains(areaDto)) {
                            result.add(areaDto);
                        }
                    }
                } else {
                    result.addAll(countyList);
                }
                break;
        }
        DataSourceHolder.clearDataSource();
        return result;
    }


}
